package Tests
{
	import Box2D.Collision.Shapes.b2EdgeShape;
	import Box2D.Collision.Shapes.b2PolygonShape;
	import Box2D.Common.Math.b2Vec2;
	import Box2D.Dynamics.Joints.b2DistanceJointDef;
	import Box2D.Dynamics.Joints.b2Joint;
	import Box2D.Dynamics.Joints.b2RevoluteJointDef;
	import Box2D.Dynamics.b2Body;
	import Box2D.Dynamics.b2BodyDef;
	import Box2D.Dynamics.b2BodyType;
	
	import Framework.Test;
	
	public class Web extends Test
	{
		private var m_bodies:Vector.<b2Body> = new Vector.<b2Body>(4);
		private var m_joints:Vector.<b2Joint> = new Vector.<b2Joint>(8);
		public function Web()
		{
			super();
			createGround();
			createWeb()
		}
		private function createGround():void{
			var shape:b2EdgeShape =new b2EdgeShape;
			shape.Set(new b2Vec2(-40,0),new b2Vec2(40,0));
			m_groundBody.CreateFixtureByShape(shape,0);
		}
		private function createWeb():void{
			var shape:b2PolygonShape = new b2PolygonShape;
			shape.SetAsBox(0.5, 0.5);
			
			var bd:b2BodyDef= new b2BodyDef;
			bd.type = b2BodyType.b2_dynamicBody;
			
			bd.position.Set(-5.0, 5.0);
			m_bodies[0] = m_world.CreateBody(bd);
			m_bodies[0].CreateFixtureByShape(shape, 5.0);
			
			bd.position.Set(5.0, 5.0);
			m_bodies[1] = m_world.CreateBody(bd);
			m_bodies[1].CreateFixtureByShape(shape, 5.0);
			
			bd.position.Set(5.0, 15.0);
			m_bodies[2] = m_world.CreateBody(bd);
			m_bodies[2].CreateFixtureByShape(shape, 5.0);
			
			bd.position.Set(-5.0, 15.0);
			m_bodies[3] = m_world.CreateBody(bd);
			m_bodies[3].CreateFixtureByShape(shape, 5.0);
			
			var jd:b2DistanceJointDef = new b2DistanceJointDef;
			var p1:b2Vec2;
			var p2:b2Vec2;
			var d:b2Vec2;
			
			jd.frequencyHz = 2.0;
			jd.dampingRatio = 0.0;
			
			jd.bodyA = m_groundBody;
			jd.bodyB = m_bodies[0];
			jd.localAnchorA.Set(-10.0, 0.0);
			jd.localAnchorB.Set(-0.5, -0.5);
			p1 = jd.bodyA.GetWorldPoint(jd.localAnchorA);
			p2 = jd.bodyB.GetWorldPoint(jd.localAnchorB);
			d = p2.Subtract(p1)
			jd.length = d.Length();
			m_joints[0] = m_world.CreateJoint(jd);
			
			jd.bodyA = m_groundBody;
			jd.bodyB = m_bodies[1];
			jd.localAnchorA.Set(10.0, 0.0);
			jd.localAnchorB.Set(0.5, -0.5);
			p1 = jd.bodyA.GetWorldPoint(jd.localAnchorA);
			p2 = jd.bodyB.GetWorldPoint(jd.localAnchorB);
			d = p2.Subtract(p1);
			jd.length = d.Length();
			m_joints[1] = m_world.CreateJoint(jd);
			
			jd.bodyA = m_groundBody;
			jd.bodyB = m_bodies[2];
			jd.localAnchorA.Set(10.0, 20.0);
			jd.localAnchorB.Set(0.5, 0.5);
			p1 = jd.bodyA.GetWorldPoint(jd.localAnchorA);
			p2 = jd.bodyB.GetWorldPoint(jd.localAnchorB);
			d = p2.Subtract(p1);
			jd.length = d.Length();
			m_joints[2] = m_world.CreateJoint(jd);
			
			jd.bodyA = m_groundBody;
			jd.bodyB = m_bodies[3];
			jd.localAnchorA.Set(-10.0, 20.0);
			jd.localAnchorB.Set(-0.5, 0.5);
			p1 = jd.bodyA.GetWorldPoint(jd.localAnchorA);
			p2 = jd.bodyB.GetWorldPoint(jd.localAnchorB);
			d = p2.Subtract(p1);
			jd.length = d.Length();
			m_joints[3] = m_world.CreateJoint(jd);
			
			jd.bodyA = m_bodies[0];
			jd.bodyB = m_bodies[1];
			jd.localAnchorA.Set(0.5, 0.0);
			jd.localAnchorB.Set(-0.5, 0.0);
			p1 = jd.bodyA.GetWorldPoint(jd.localAnchorA);
			p2 = jd.bodyB.GetWorldPoint(jd.localAnchorB);
			d = p2.Subtract(p1);
			jd.length = d.Length();
			m_joints[4] = m_world.CreateJoint(jd);
			
			jd.bodyA = m_bodies[1];
			jd.bodyB = m_bodies[2];
			jd.localAnchorA.Set(0.0, 0.5);
			jd.localAnchorB.Set(0.0, -0.5);
			p1 = jd.bodyA.GetWorldPoint(jd.localAnchorA);
			p2 = jd.bodyB.GetWorldPoint(jd.localAnchorB);
			d = p2.Subtract(p1);
			jd.length = d.Length();
			m_joints[5] = m_world.CreateJoint(jd);
			
			jd.bodyA = m_bodies[2];
			jd.bodyB = m_bodies[3];
			jd.localAnchorA.Set(-0.5, 0.0);
			jd.localAnchorB.Set(0.5, 0.0);
			p1 = jd.bodyA.GetWorldPoint(jd.localAnchorA);
			p2 = jd.bodyB.GetWorldPoint(jd.localAnchorB);
			d = p2.Subtract(p1);
			jd.length = d.Length();
			m_joints[6] = m_world.CreateJoint(jd);
			
			jd.bodyA = m_bodies[3];
			jd.bodyB = m_bodies[0];
			jd.localAnchorA.Set(0.0, -0.5);
			jd.localAnchorB.Set(0.0, 0.5);
			p1 = jd.bodyA.GetWorldPoint(jd.localAnchorA);
			p2 = jd.bodyB.GetWorldPoint(jd.localAnchorB);
			d = p2.Subtract(p1);
			jd.length = d.Length();
			m_joints[7] = m_world.CreateJoint(jd);
			
		}
		public override function Key(key:String):void
		{
			var i:int;
			switch (key)
			{
				case 'b':
					for ( i = 0; i < 4; ++i)
					{
						if (m_bodies[i])
						{
							m_world.DestroyBody(m_bodies[i]);
							m_bodies[i] = null;
							break;
						}
					}
					break;
				
				case 'j':
					for ( i = 0; i < 8; ++i)
					{
						if (m_joints[i])
						{
							m_world.DestroyJoint(m_joints[i]);
							m_joints[i] = null;
							break;
						}
					}
					break;
			}
		}
		public override function Step():void{
			super.Step();
			writeMessage('This demonstrates a soft distance joint.');			
		}
		public override function get hotKeyNote():String{return 'Press: (b) to delete a body, (j) to delete a joint'}
		public override function JointDestroyed(joint:b2Joint):void
		{
			for (var i:int = 0; i < 8; ++i)
			{
				if (m_joints[i] == joint)
				{
					m_joints[i] = null;
					break;
				}
			}
		}
	}
}